import java.awt.Point;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import javax.swing.JOptionPane;

public class Tools
{
	public static boolean CheckHeapSize()
	{ // returns false if heap usage is dangerously high

		// https://stackoverflow.com/questions/2015463/how-to-view-the-current-heap-size-that-an-application-is-using

		long HeapSize = Runtime.getRuntime().totalMemory();
		long HeapSizeMax = Runtime.getRuntime().maxMemory();

		// System.out.println(HeapSize + " " + HeapSizeMax);

		if (HeapSize > 4L * 1024L * 1024L * 1024L - 500L * 1024L * 1024L) // leave 500 MB
			return false;
		if (HeapSize >= HeapSizeMax - 500L * 1024L * 1024L) // leave 500 MB
			return false;

		return true;
	}

	// WriteUTF32Bit()/ReadUTF32Bit() in the present states have been tested with
	// "aaaaaaaaaa..." strings of ALL lengths from 0 to 100000, the read strings
	// were always identical to the written ones (code seems to be reliable).

	private final static int UTF32BitContinue = ((int) '3' << 24) + ((int) '2' << 16) + ((int) 'b' << 8) + ((int) 'c');
	private final static int UTF32BitEnd = ((int) '3' << 24) + ((int) '2' << 16) + ((int) 'b' << 8) + ((int) 'e');

	public static String ReadUTF32Bit(DataInputStream is) throws IOException
	{
		String S = ""; // don't think StringBuilder creation and .toString() overhead is worth it (mostly we do one while (true)-iteration only)

		while (true)
		{
			int Marking = is.readInt();
			if (Marking == UTF32BitContinue)
				S = S + is.readUTF();
			else if (Marking == UTF32BitEnd) // it might be that there's ONLY one end marking in file, no continue marking and no actual string!
				break;
			else
				throw new IOException("ReadUTF32Bit(): format screwed");
		}

		return S;
	}

	public static String ShowInputDialog(String Message)
	{
		return JOptionPane.showInputDialog(Message);
	}
	
	public static String ShowInputDialog(String Message, String DefaultText)
	{
		return JOptionPane.showInputDialog(Message, DefaultText);
	}

	public static void ShowMessageDialog(MainWindow ParentComponentOrNull, String Message)
	{
		if (!(Message.endsWith(".") || Message.endsWith("...") || Message.endsWith("!") || Message.endsWith("?")))
			if (!(Message.endsWith(" ") || Message.endsWith("\t")))
				Message = Message + ".";

		JOptionPane.showMessageDialog(ParentComponentOrNull, Message.trim());
	}

	public static boolean ShowYesNoDialog(MainWindow ParentComponentOrNull, String Message)
	{
		if (!(Message.endsWith(".") || Message.endsWith("...") || Message.endsWith("!") || Message.endsWith("?")))
			if (!(Message.endsWith(" ") || Message.endsWith("\t")))
				Message = Message + ".";

		int DialogResult = JOptionPane.showConfirmDialog(ParentComponentOrNull, Message.trim(), "Question", JOptionPane.YES_NO_OPTION);

		return (DialogResult == JOptionPane.YES_OPTION);
	}

	public static Point SubtractPoints(Point p1, Point p2)
	{
		return new Point(p1.x - p2.x, p1.y - p2.y);
	}

	public static void WriteUTF32Bit(DataOutputStream os, String S) throws IOException
	{
		// Java's .writeUTF() can only save 16-bit string lengths, so we NEED to implement
		// our own string writing/reading (sites on the Internet did recommend this, too)

		int StartIndex = 0;
		int EndIndex = 10000;

		while (true)
		{
			if (StartIndex < S.length()) // don't write ""
			{
				os.writeInt(UTF32BitContinue);
				os.writeUTF(S.substring(StartIndex, Math.min(S.length(), EndIndex))); // if writing "", end marking is not written correctly (just 32-bit 0), don't know why

				StartIndex += 10000;
				EndIndex += 10000;
			}
			else
			{
				break;
			}
		}
		os.writeInt(UTF32BitEnd);
	}
}
